package org.dding.msc.service.management;

import java.beans.ConstructorProperties;
import java.io.Serializable;

/**
 * A representation of the current status of some service.
 * 
 */
public class ServiceStatus implements Serializable {

	private static final long serialVersionUID = 6538576441150451665L;

	private final String serviceName;
	private final String[] aliases;
	private final String serviceClassName;
	private final String modeName;
	private final String stateName;
	private final String substateName;
	private final String exception;

	/**
	 * Construct a new instance.
	 * 
	 * @param parentName
	 *            the name of the parent
	 * @param serviceName
	 *            the service name
	 * @param aliases
	 *            the aliases of this service
	 * @param serviceClassName
	 *            the name of the service class
	 * @param modeName
	 *            the service mode name
	 * @param stateName
	 *            the service state name
	 * @param substateName
	 *            the internal service substate name
	 * @param dependencies
	 *            the list of dependencies for this service
	 * @param dependencyFailed
	 *            {@code true} if some dependency is failed
	 * @param exception
	 *            the service start exception
	 * @param dependencyUnavailable
	 *            {@code true} if some dependency is unavailable
	 */
	@ConstructorProperties({"serviceName", "serviceClassName",
			"modeName", "stateName", "substateName", "exception" })
	public ServiceStatus(final String serviceName,
			final String[] aliases, final String serviceClassName,
			final String modeName, final String stateName,
			final String substateName, final String exception) {
		if (serviceName == null) {
			throw new IllegalArgumentException("serviceName is null");
		}
		if (aliases == null) {
			throw new IllegalArgumentException("aliases is null");
		}
		if (serviceClassName == null) {
			throw new IllegalArgumentException("serviceClassName is null");
		}
		if (modeName == null) {
			throw new IllegalArgumentException("modeName is null");
		}
		if (stateName == null) {
			throw new IllegalArgumentException("stateName is null");
		}
		if (substateName == null) {
			throw new IllegalArgumentException("substateName is null");
		}
		this.serviceName = serviceName;
		this.aliases = aliases;
		this.serviceClassName = serviceClassName;
		this.modeName = modeName;
		this.stateName = stateName;
		this.substateName = substateName;
		this.exception = exception;
	}

	/**
	 * Get the service name, as a string.
	 * 
	 * @return the service name
	 */
	public String getServiceName() {
		return serviceName;
	}

	/**
	 * Get the service aliases, if any, as strings. If there are no aliases, an
	 * empty array is returned.
	 * 
	 * @return the service aliases
	 */
	public String[] getAliases() {
		return aliases;
	}

	/**
	 * Get the service class name, or {@code "&lt;unknown&gt;"} if not known.
	 * 
	 * @return the service class name
	 */
	public String getServiceClassName() {
		return serviceClassName;
	}

	/**
	 * Get the service mode, as a string.
	 * 
	 * @return the service mode
	 */
	public String getModeName() {
		return modeName;
	}

	/**
	 * Get the service state, as a string.
	 * 
	 * @return the service state
	 */
	public String getStateName() {
		return stateName;
	}

	/**
	 * Get the service internal substate, as a string.
	 * 
	 * @return the service substate
	 */
	public String getSubstateName() {
		return substateName;
	}

	/**
	 * Get the service start exception.
	 * 
	 * @return the service start exception
	 */
	public String getException() {
		return exception;
	}

	/**
	 * Get a string representation of the current status.
	 * 
	 * @return a string representation
	 */
	public String toString() {
		final StringBuilder builder = new StringBuilder();
		builder.append("Service \"").append(serviceName).append("\" ");
		final String[] aliases = this.aliases;
		if (aliases.length > 0) {
			builder.append("(aliases: ");
			for (int i = 0; i < aliases.length; i++) {
				builder.append(aliases[i]);
				if (i < aliases.length - 1) {
					builder.append(", ");
				}
			}
			builder.append(") ");
		}
		builder.append("(class ").append(serviceClassName).append(')');
		builder.append(" mode ").append(modeName);
		builder.append(" state ").append(stateName);
		if (!stateName.equals(substateName)) {
			builder.append(" (").append(substateName).append(')');
		}
		String exception = this.exception;
		if (exception != null && !exception.isEmpty()) {
			builder.append(" (failure cause: ").append(exception).append(')');
		}
		return builder.toString();
	}
}
